﻿using G19Glower.Shared;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace G19Glower.App
{
    internal class GlowerApplication : IServicesProvider
    {
        private List<GlowerDetails> mGlowers = new List<GlowerDetails>();
        private KeyboardHooker mKeyboardHooker = new KeyboardHooker();
        private GlowController mGlowController = new GlowController();
        private SettingsManager mSettingsManager = new SettingsManager();

        #region .ctor

        internal GlowerApplication()
        {
            this.InitalizeComponents();
            
            mKeyboardHooker.SetHook();
            
            this.TrayIcon.Visible = true;

            this.LoadGlowers();
        }

        #endregion

        #region Event Handlers

        private void SettingsItem_Click(object sender, EventArgs e)
        {
            this.ShowSettings();
        }

        private void CloseItem_Click(object sender, EventArgs e)
        {
            mKeyboardHooker.UnsetHook();

            Application.Exit();
        }

        #endregion

        #region Private Methods

        private void LoadGlowers()
        {
            var runningGlowies = mSettingsManager.GetRunningGlowies().ToArray();
            var runOverride = !mSettingsManager.IsSaved;

            foreach (Type glowerType in typeof(G19Glower.Glowies.LinearGlower).Assembly.GetTypes().Where(type => typeof(IGlower).IsAssignableFrom(type)))
            {
                try
                {
                    var glowerInstance = Activator.CreateInstance(glowerType) as IGlower;
                    var glowerDetails = new GlowerDetails(glowerInstance);

                    mGlowers.Add(glowerDetails);
                    glowerInstance.Initialize(this);

                    glowerDetails.DesiredRunningState = runOverride || runningGlowies.Contains(glowerType.FullName);
                    glowerDetails.ApplyDesiredRunningState();

                    runOverride = false;
                }
                catch
                {

                }
            }
        }

        private void ShowSettings()
        {
            if (mShowingSettings)
            {
                return;
            }

            // Make sure we don't show 2 windows
            mShowingSettings = true;

            var settingsWindow = new SettingsWindow();
            settingsWindow.Initialize(mGlowers, mSettingsManager);
            
            // Show settings
            settingsWindow.ShowDialog();

            mShowingSettings = false;
        }

        #endregion

        #region UI

        private NotifyIcon TrayIcon;
        private ToolStripItem SettingsItem;
        private ToolStripItem CloseItem;
        private bool mShowingSettings;

        private void InitalizeComponents()
        {
            this.TrayIcon = new NotifyIcon();
            this.TrayIcon.Icon = G19Glower.App.Properties.Resources.Something;
            this.TrayIcon.Text = "G19 Glower";

            // Give the tray jazz some flare
            this.TrayIcon.ContextMenuStrip = new ContextMenuStrip();

            this.SettingsItem = this.TrayIcon.ContextMenuStrip.Items.Add("&Settings");
            this.SettingsItem.Click += new EventHandler(this.SettingsItem_Click);

            this.CloseItem = this.TrayIcon.ContextMenuStrip.Items.Add("&Close");
            this.CloseItem.Click += new EventHandler(this.CloseItem_Click);

            this.TrayIcon.DoubleClick += new EventHandler(this.SettingsItem_Click);
        }

        #endregion

        #region IServicesProvider Members

        TServiceType IServicesProvider.GetService<TServiceType>()
        {
            if (mKeyboardHooker is TServiceType)
            {
                return (TServiceType)(object)mKeyboardHooker;
            }
            else if (mGlowController is TServiceType)
            {
                return (TServiceType)(object)mGlowController;
            }
            else if (mSettingsManager is TServiceType)
            {
                return (TServiceType)(object)mSettingsManager;
            }
            
            return default(TServiceType);
        }

        #endregion
    }
}
